package com.dragon.mmochat.service;

import java.awt.Color;
import java.io.File;
import java.net.URL;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;

import com.dragon.mmochat.MmochatConstant;
import com.dragon.mmochat.MmochatMain;
import com.dragon.mmochat.message.Mmochat_1_7S;
import com.dragon.mmochat.message.Mmochat_4_10C;
import com.dragon.mmochat.message.Mmochat_4_11S;
import com.dragon.mmochat.message.Mmochat_4_12S;
import com.dragon.mmochat.message.Mmochat_4_13C;
import com.dragon.mmochat.message.Mmochat_4_13S;
import com.dragon.mmochat.message.Mmochat_4_14S;
import com.dragon.mmochat.message.Mmochat_4_1C;
import com.dragon.mmochat.message.Mmochat_4_2C;
import com.dragon.mmochat.message.Mmochat_4_3C;
import com.dragon.mmochat.message.Mmochat_4_4C;
import com.dragon.mmochat.message.Mmochat_4_4S;
import com.dragon.mmochat.message.Mmochat_4_5C;
import com.dragon.mmochat.message.Mmochat_4_6C;
import com.dragon.mmochat.message.Mmochat_4_7C;
import com.dragon.mmochat.message.Mmochat_4_9S;
import com.dragon.mmochat.model.MmochatActivityInfo;
import com.dragon.mmochat.model.MmochatDailyActivity;
import com.dragon.mmochat.model.MmochatTeam;
import com.dragon.mmochat.model.award.MmochatEquipAward;
import com.dragon.mmochat.model.enumType.MmochatDailyActivityType;
import com.dragon.mmochat.model.enumType.MmochatDrugType;
import com.dragon.mmochat.model.enumType.MmochatEquipQualityType;
import com.dragon.mmochat.model.enumType.MmochatEquipType;
import com.dragon.mmochat.model.enumType.MmochatMaterialType;
import com.dragon.mmochat.model.enumType.MmochatNpcItemType;
import com.dragon.mmochat.model.enumType.MmochatNpcState;
import com.dragon.mmochat.model.enumType.MmochatPropType;
import com.dragon.mmochat.model.enumType.MmochatRoleType;
import com.dragon.mmochat.model.enumType.MmochatTaskStateType;
import com.dragon.mmochat.model.enumType.MmochatTaskType;
import com.dragon.mmochat.model.gang.MmochatGang;
import com.dragon.mmochat.model.gang.MmochatGangMember;
import com.dragon.mmochat.model.map.MmochatMap;
import com.dragon.mmochat.model.map.MmochatMapPoint;
import com.dragon.mmochat.model.object.MmochatDrug;
import com.dragon.mmochat.model.object.MmochatMaterial;
import com.dragon.mmochat.model.role.MmochatMonster;
import com.dragon.mmochat.model.role.MmochatNpc;
import com.dragon.mmochat.model.role.MmochatPet;
import com.dragon.mmochat.model.role.MmochatPlayer;
import com.dragon.mmochat.model.role.MmochatTempNpc;
import com.dragon.mmochat.model.task.MmochatKillMonster;
import com.dragon.mmochat.model.task.MmochatNpcBattle;
import com.dragon.mmochat.model.task.MmochatTask;
import com.dragon.mmochat.model.task.MmochatTaskTalk;
import com.dragon.mmochat.service.MmochatBattleService.saveSqlAfterBattleAction;
import com.dragon.mmochat.service.MmochatPropService.doSql;
import com.dragon.mmochat.util.CallLocalFuncTlv;
import com.dragon.mmochat.util.CreateMsgBoxTLVWithBmp;
import com.dragon.mmochat.util.CreateTlvWin;
import com.dragon.mmochat.util.MmochatUtil;
import com.skymobi.handler.SkymobiHandler;
import com.skymobi.message.SkymobiProtocolMessage;
import com.skymobi.message.widget.AddDataTLV;
import com.skymobi.message.widget.ClearDataTLV;
import com.skymobi.message.widget.CloseWinTLV;
import com.skymobi.message.widget.CreateMsgBoxTLV;
import com.skymobi.message.widget.CtrlTLVStructureRequest;
import com.skymobi.message.widget.SendDataTLV;
import com.skymobi.message.widget.ShowPopupMenuTLV;
import com.skymobi.message.widget.ShowWaitingMsgBoxTLV;
import com.skymobi.message.widget.TLVStructure;
import com.skymobi.message.widget.WinType;
import com.skymobi.service.SkymobiService;
import com.skymobi.util.Text;

public class MmochatTaskService {
	private static Logger log = LoggerFactory
			.getLogger(MmochatTaskService.class);

	public static ScheduledExecutorService updateSqlAfterTaskThread = Executors
			.newScheduledThreadPool(1);

	// 需要保存完成任务后数据库的角色队列
	public static ConcurrentLinkedQueue<MmochatPlayer> needToSaveTaskSqlPlayerQueue = new ConcurrentLinkedQueue<MmochatPlayer>();
	// 押镖任务
	public static Map<Integer, MmochatTask> YBTasks = new ConcurrentHashMap<Integer, MmochatTask>();
	// 常规任务
	public static Map<Integer, MmochatTask> tasks = new ConcurrentHashMap<Integer, MmochatTask>();
	// 日常活动
	public static List<MmochatActivityInfo> dailyActivities = new ArrayList<MmochatActivityInfo>();
	// 推荐活动
	public static List<MmochatActivityInfo> suggestActivities = new ArrayList<MmochatActivityInfo>();

	// 允许远程访问的NPC的ID
	public static int[] romoteNpcIds = new int[] { 305, 72, 73, 74 };

	// 从配置文件初始化任务
	public MmochatTaskService() {
		if (!MmochatMain.openMergeServer) {
			updateSqlAfterTaskThread.scheduleAtFixedRate(
					new saveSqlAfterTaskAction(), 60000, 13000,
					TimeUnit.MILLISECONDS);

			try {
				File root = new File("task");
				File[] files = root.listFiles();
				if (files != null) {
					for (File file : files) {
						if (!file.isFile()) {
							continue;
						}
						DocumentBuilderFactory docBuilderFactory = DocumentBuilderFactory
								.newInstance();
						DocumentBuilder docBuilder = docBuilderFactory
								.newDocumentBuilder();
						Document doc = docBuilder.parse(file);

						// normalize text redivsentation
						doc.getDocumentElement().normalize();
						NodeList listOfTask = doc.getElementsByTagName("task");
						log.debug("task num = " + listOfTask.getLength());

						for (int s = 0; s < listOfTask.getLength(); s++) {
							Node firstTaskNode = listOfTask.item(s);
							if (firstTaskNode.getNodeType() == Node.ELEMENT_NODE) {
								MmochatTask task = new MmochatTask();
								Element firstTaskElement = (Element) firstTaskNode;
								// 读取taskId
								NodeList taskIdList = firstTaskElement
										.getElementsByTagName("taskId");
								String taskIdStr = taskIdList.item(0)
										.getChildNodes().item(0).getNodeValue()
										.trim();
								int taskId = Integer.parseInt(taskIdStr);
								if (tasks.get(taskId) != null) {
									throw new RuntimeException("任务ID重复,"
											+ file.getName() + ",taskId="
											+ taskId);
								}
								task.setTaskId(taskId);
								log.debug(file.getName() + ",加载任务:taskId="
										+ taskId);
								// 读取taskName
								NodeList taskNameList = firstTaskElement
										.getElementsByTagName("taskName");
								String taskName = taskNameList.item(0)
										.getChildNodes().item(0).getNodeValue()
										.trim();
								task.setTaskName(taskName);

								// 读取taskType
								NodeList taskTypeList = firstTaskElement
										.getElementsByTagName("taskType");
								String taskTypeStr = taskTypeList.item(0)
										.getChildNodes().item(0).getNodeValue()
										.trim();
								int taskType = Integer.parseInt(taskTypeStr);
								task.setTaskType(MmochatTaskType.get(taskType));

								// 读取canReject
								NodeList canRejectList = firstTaskElement
										.getElementsByTagName("canReject");
								if (canRejectList.getLength() > 0) {
									String canRejectStr = canRejectList.item(0)
											.getChildNodes().item(0)
											.getNodeValue().trim();
									if (canRejectStr.equals("false")) {
										task.setCanReject(false);
									} else {
										task.setCanReject(true);
									}
								}

								// 读取hintKey
								NodeList hintKeyList = firstTaskElement
										.getElementsByTagName("hintKey");
								if (hintKeyList.getLength() > 0) {
									String hintKeyStr = hintKeyList.item(0)
											.getChildNodes().item(0)
											.getNodeValue().trim();
									if (hintKeyStr.equals("0键")) {
										task
												.setHintKey(MmochatConstant.MR_KEY_0);
									} else if (hintKeyStr.equals("1键")) {
										task
												.setHintKey(MmochatConstant.MR_KEY_1);
									} else if (hintKeyStr.equals("2键")) {
										task
												.setHintKey(MmochatConstant.MR_KEY_2);
									} else if (hintKeyStr.equals("3键")) {
										task
												.setHintKey(MmochatConstant.MR_KEY_3);
									} else if (hintKeyStr.equals("4键")) {
										task
												.setHintKey(MmochatConstant.MR_KEY_4);
									} else if (hintKeyStr.equals("5键")) {
										task
												.setHintKey(MmochatConstant.MR_KEY_5);
									} else if (hintKeyStr.equals("6键")) {
										task
												.setHintKey(MmochatConstant.MR_KEY_6);
									} else if (hintKeyStr.equals("7键")) {
										task
												.setHintKey(MmochatConstant.MR_KEY_7);
									} else if (hintKeyStr.equals("8键")) {
										task
												.setHintKey(MmochatConstant.MR_KEY_8);
									} else if (hintKeyStr.equals("9键")) {
										task
												.setHintKey(MmochatConstant.MR_KEY_9);
									} else if (hintKeyStr.equals("*键")) {
										task
												.setHintKey(MmochatConstant.MR_KEY_STAR);
									} else if (hintKeyStr.equals("#键")) {
										task
												.setHintKey(MmochatConstant.MR_KEY_POUND);
									} else if (hintKeyStr.equals("左软键")) {
										task
												.setHintKey(MmochatConstant.MR_KEY_SOFTLEFT);
									} else if (hintKeyStr.equals("右软键")) {
										task
												.setHintKey(MmochatConstant.MR_KEY_SOFTRIGHT);
									} else if (hintKeyStr.equals("拨号键")) {
										task
												.setHintKey(MmochatConstant.MR_KEY_SEND);
									}

								}

								// 读取hintWord
								NodeList hintWordList = firstTaskElement
										.getElementsByTagName("hintWord");
								if (hintWordList.getLength() > 0) {
									String hintWord = hintWordList.item(0)
											.getChildNodes().item(0)
											.getNodeValue().trim();
									task.setHintWord(hintWord);
								}

								// 读取showInTaskList
								NodeList showInTaskListList = firstTaskElement
										.getElementsByTagName("showInTaskList");
								if (showInTaskListList.getLength() > 0) {
									String showInTaskStr = showInTaskListList
											.item(0).getChildNodes().item(0)
											.getNodeValue().trim();
									if (showInTaskStr.equals("false")) {
										task.setShowInTaskList(false);
									} else {
										task.setShowInTaskList(true);
									}
								}

								// 读取accept_npcId
								Integer accept_npcId = null;
								NodeList accept_npcIdList = firstTaskElement
										.getElementsByTagName("accept_npcId");
								if (accept_npcIdList != null
										&& accept_npcIdList.getLength() > 0) {
									String accept_npcIdStr = accept_npcIdList
											.item(0).getChildNodes().item(0)
											.getNodeValue().trim();
									accept_npcId = Integer
											.parseInt(accept_npcIdStr);
									task.setAccept_npcId(accept_npcId);
								}

								// 读取accept_minLevel
								NodeList accept_minLevelList = firstTaskElement
										.getElementsByTagName("accept_minLevel");
								if (accept_minLevelList != null
										&& accept_minLevelList.getLength() > 0) {
									String accept_minLevelStr = accept_minLevelList
											.item(0).getChildNodes().item(0)
											.getNodeValue().trim();
									int accept_minLevel = Integer
											.parseInt(accept_minLevelStr);
									task.setAccept_minLevel(accept_minLevel);
								}

								// 读取accept_maxLevel
								NodeList accept_maxLevelList = firstTaskElement
										.getElementsByTagName("accept_maxLevel");
								if (accept_maxLevelList != null
										&& accept_maxLevelList.getLength() > 0) {
									String accept_maxLevelStr = accept_maxLevelList
											.item(0).getChildNodes().item(0)
											.getNodeValue().trim();
									int accept_maxLevel = Integer
											.parseInt(accept_maxLevelStr);
									task.setAccept_maxLevel(accept_maxLevel);
								}

								// 读取accept_preTaskIds
								NodeList accept_preTaskIdList = firstTaskElement
										.getElementsByTagName("accept_preTaskId");
								for (int t = 0; t < accept_preTaskIdList
										.getLength(); t++) {
									String accept_preTaskIdStr = accept_preTaskIdList
											.item(t).getChildNodes().item(0)
											.getNodeValue().trim();
									int accept_preTaskId = Integer
											.parseInt(accept_preTaskIdStr);
									task.addAccept_preTaskId(accept_preTaskId);
								}

								// 读取accept_talk列表
								NodeList accept_talkList = firstTaskElement
										.getElementsByTagName("accept_talk");
								for (int t = 0; t < accept_talkList.getLength(); t++) {
									String accept_talk = accept_talkList
											.item(t).getChildNodes().item(0)
											.getNodeValue().trim();
									task.addAccept_talk(accept_talk);
								}

								// 读取taskDetail
								NodeList taskDetailList = firstTaskElement
										.getElementsByTagName("taskDetail");
								String taskDetail = taskDetailList.item(0)
										.getChildNodes().item(0).getNodeValue()
										.trim();
								task.setTaskDetail(taskDetail);

								// 读取taskContinue
								NodeList taskContinueList = firstTaskElement
										.getElementsByTagName("taskContinue");
								if (taskContinueList.getLength() > 0) {
									String taskContinueStr = taskContinueList
											.item(0).getChildNodes().item(0)
											.getNodeValue().trim();
									if (taskContinueStr.equals("true")) {
										task.setTaskContinue(true);
									} else if (taskContinueStr.equals("false")) {
										task.setTaskContinue(false);
									}
								}

								// 读取finishAnotherTask
								NodeList finishAnotherTaskList = firstTaskElement
										.getElementsByTagName("finishAnotherTask");
								if (finishAnotherTaskList.getLength() > 0) {
									String finishAnotherTaskStr = finishAnotherTaskList
											.item(0).getChildNodes().item(0)
											.getNodeValue().trim();
									int finishAnotherTaskId = Integer
											.parseInt(finishAnotherTaskStr);
									task
											.setFinishAnotherTaskId(finishAnotherTaskId);
								}

								// 读取finish_npcId
								NodeList finish_npcIdList = firstTaskElement
										.getElementsByTagName("finish_npcId");
								String finish_npcIdStr = finish_npcIdList.item(
										0).getChildNodes().item(0)
										.getNodeValue().trim();
								int finish_npcId = Integer
										.parseInt(finish_npcIdStr);
								task.setFinish_npcId(finish_npcId);

								// 读取finish_talk列表
								NodeList finish_talkList = firstTaskElement
										.getElementsByTagName("finish_talk");
								for (int t = 0; t < finish_talkList.getLength(); t++) {
									String finish_talk = finish_talkList
											.item(t).getChildNodes().item(0)
											.getNodeValue().trim();
									task.addFinish_talk(finish_talk);
								}

								// 读取finish_award_exp
								NodeList finish_award_expList = firstTaskElement
										.getElementsByTagName("finish_award_exp");
								if (finish_award_expList != null
										&& finish_award_expList.getLength() > 0) {
									String finish_award_expStr = finish_award_expList
											.item(0).getChildNodes().item(0)
											.getNodeValue().trim();
									int finish_award_exp = Integer
											.parseInt(finish_award_expStr);
									task.setFinish_award_exp(finish_award_exp);
								}

								// 读取finish_award_expTimes
								NodeList finish_award_expTimesList = firstTaskElement
										.getElementsByTagName("finish_award_expTimes");
								if (finish_award_expTimesList != null
										&& finish_award_expTimesList
												.getLength() > 0) {
									String finish_award_expTimesListStr = finish_award_expTimesList
											.item(0).getChildNodes().item(0)
											.getNodeValue().trim();
									int finish_award_expTimes = Integer
											.parseInt(finish_award_expTimesListStr);
									task
											.setFinish_award_expTimes(finish_award_expTimes);
								}

								// 读取finish_award_dao
								NodeList finish_award_daoList = firstTaskElement
										.getElementsByTagName("finish_award_dao");
								if (finish_award_daoList != null
										&& finish_award_daoList.getLength() > 0) {
									String finish_award_daoStr = finish_award_daoList
											.item(0).getChildNodes().item(0)
											.getNodeValue().trim();
									int finish_award_dao = Integer
											.parseInt(finish_award_daoStr);
									task.setFinish_award_dao(finish_award_dao);
								}

								// 读取killList
								NodeList killList = firstTaskElement
										.getElementsByTagName("killMonster");
								for (int t = 0; t < killList.getLength(); t++) {
									Node firstKillNode = killList.item(t);
									if (firstKillNode.getNodeType() == Node.ELEMENT_NODE) {
										MmochatKillMonster kill = new MmochatKillMonster();
										Element firstKillElement = (Element) firstKillNode;
										// 读取name
										NodeList nameList = firstKillElement
												.getElementsByTagName("name");
										String name = nameList.item(0)
												.getChildNodes().item(0)
												.getNodeValue().trim();
										kill.setMonsterType(MmochatRoleType
												.valueOf(name));

										// 读取num
										NodeList numList = firstKillElement
												.getElementsByTagName("num");
										String numStr = numList.item(0)
												.getChildNodes().item(0)
												.getNodeValue().trim();
										int num = Integer.parseInt(numStr);
										kill.setMonsterNum(num);
										task.addKillTask(kill);
									}
								}

								// 读取finish_need_materials
								NodeList finish_need_material = firstTaskElement
										.getElementsByTagName("finish_need_material");
								for (int t = 0; t < finish_need_material
										.getLength(); t++) {
									Node firstMaterialNode = finish_need_material
											.item(t);
									if (firstMaterialNode.getNodeType() == Node.ELEMENT_NODE) {
										MmochatMaterial material = new MmochatMaterial();
										Element firstMaterialElement = (Element) firstMaterialNode;
										// 读取name
										NodeList nameList = firstMaterialElement
												.getElementsByTagName("name");
										String name = nameList.item(0)
												.getChildNodes().item(0)
												.getNodeValue().trim();
										material.setType(MmochatMaterialType
												.valueOf(name));

										// 读取num
										NodeList numList = firstMaterialElement
												.getElementsByTagName("num");
										String numStr = numList.item(0)
												.getChildNodes().item(0)
												.getNodeValue().trim();
										int num = Integer.parseInt(numStr);
										material.setNum(num);
										task.addFinish_need_material(material);
									}
								}

								// 读取finish_need_drug
								NodeList finish_need_drug = firstTaskElement
										.getElementsByTagName("finish_need_drug");
								for (int t = 0; t < finish_need_drug
										.getLength(); t++) {
									Node firstDrugNode = finish_need_drug
											.item(t);
									if (firstDrugNode.getNodeType() == Node.ELEMENT_NODE) {
										MmochatDrug drug = new MmochatDrug();
										Element firstDrugElement = (Element) firstDrugNode;
										// 读取name
										NodeList nameList = firstDrugElement
												.getElementsByTagName("name");
										String name = nameList.item(0)
												.getChildNodes().item(0)
												.getNodeValue().trim();

										drug.setType(MmochatDrugType
												.valueOf(name));

										// 读取num
										NodeList numList = firstDrugElement
												.getElementsByTagName("num");
										String numStr = numList.item(0)
												.getChildNodes().item(0)
												.getNodeValue().trim();
										int num = Integer.parseInt(numStr);
										drug.setNum(num);
										task.addFinish_need_drug(drug);
									}
								}

								// 读取finish_need_money
								NodeList finish_need_moneyList = firstTaskElement
										.getElementsByTagName("finish_need_money");
								if (finish_need_moneyList != null
										&& finish_need_moneyList.getLength() > 0) {
									String finish_need_moneyStr = finish_need_moneyList
											.item(0).getChildNodes().item(0)
											.getNodeValue().trim();
									int finish_need_money = Integer
											.parseInt(finish_need_moneyStr);
									task
											.setFinish_need_money(finish_need_money);
								}

								// 读取finish_need_zhanji
								NodeList finish_need_zhanjiList = firstTaskElement
										.getElementsByTagName("finish_need_zhanji");
								if (finish_need_zhanjiList != null
										&& finish_need_zhanjiList.getLength() > 0) {
									String finish_need_zhanjiStr = finish_need_zhanjiList
											.item(0).getChildNodes().item(0)
											.getNodeValue().trim();
									int finish_need_zhanji = Integer
											.parseInt(finish_need_zhanjiStr);
									task
											.setFinish_need_zhanji(finish_need_zhanji);
								}

								// 读取finish_award_materials
								NodeList finish_award_material = firstTaskElement
										.getElementsByTagName("finish_award_material");
								for (int t = 0; t < finish_award_material
										.getLength(); t++) {
									Node firstMaterialNode = finish_award_material
											.item(t);
									if (firstMaterialNode.getNodeType() == Node.ELEMENT_NODE) {
										MmochatMaterial material = new MmochatMaterial();
										Element firstMaterialElement = (Element) firstMaterialNode;
										// 读取name
										NodeList nameList = firstMaterialElement
												.getElementsByTagName("name");
										String name = nameList.item(0)
												.getChildNodes().item(0)
												.getNodeValue().trim();
										material.setType(MmochatMaterialType
												.valueOf(name));

										// 读取num
										NodeList numList = firstMaterialElement
												.getElementsByTagName("num");
										String numStr = numList.item(0)
												.getChildNodes().item(0)
												.getNodeValue().trim();
										int num = Integer.parseInt(numStr);
										material.setNum(num);
										task.addFinish_award_material(material);
									}
								}

								// 读取finish_award_drug
								NodeList finish_award_drug = firstTaskElement
										.getElementsByTagName("finish_award_drug");
								for (int t = 0; t < finish_award_drug
										.getLength(); t++) {
									Node firstDrugNode = finish_award_drug
											.item(t);
									if (firstDrugNode.getNodeType() == Node.ELEMENT_NODE) {
										MmochatDrug drug = new MmochatDrug();
										Element firstDrugElement = (Element) firstDrugNode;
										// 读取name
										NodeList nameList = firstDrugElement
												.getElementsByTagName("name");
										String name = nameList.item(0)
												.getChildNodes().item(0)
												.getNodeValue().trim();

										drug.setType(MmochatDrugType
												.valueOf(name));

										// 读取num
										NodeList numList = firstDrugElement
												.getElementsByTagName("num");
										String numStr = numList.item(0)
												.getChildNodes().item(0)
												.getNodeValue().trim();
										int num = Integer.parseInt(numStr);
										drug.setNum(num);
										task.addFinish_award_drug(drug);
									}
								}

								// 读取finish_award_money
								NodeList finish_award_moneyList = firstTaskElement
										.getElementsByTagName("finish_award_money");
								if (finish_award_moneyList != null
										&& finish_award_moneyList.getLength() > 0) {
									String finish_award_moneyStr = finish_award_moneyList
											.item(0).getChildNodes().item(0)
											.getNodeValue().trim();
									int finish_award_money = Integer
											.parseInt(finish_award_moneyStr);
									task
											.setFinish_award_money(finish_award_money);
								}

								// 读取finish_award_gangBuild
								NodeList finish_award_gangBuildList = firstTaskElement
										.getElementsByTagName("finish_award_gangBuild");
								if (finish_award_gangBuildList != null
										&& finish_award_gangBuildList
												.getLength() > 0) {
									String finish_award_gangBuildStr = finish_award_gangBuildList
											.item(0).getChildNodes().item(0)
											.getNodeValue().trim();
									int finish_award_gangBuild = Integer
											.parseInt(finish_award_gangBuildStr);
									task
											.setFinish_award_gangBuild(finish_award_gangBuild);
								}

								// 读取finish_award_gangMoney
								NodeList finish_award_gangMoneyList = firstTaskElement
										.getElementsByTagName("finish_award_gangMoney");
								if (finish_award_gangMoneyList != null
										&& finish_award_gangMoneyList
												.getLength() > 0) {
									String finish_award_gangMoneyStr = finish_award_gangMoneyList
											.item(0).getChildNodes().item(0)
											.getNodeValue().trim();
									int finish_award_gangMoney = Integer
											.parseInt(finish_award_gangMoneyStr);
									task
											.setFinish_award_gangMoney(finish_award_gangMoney);
								}

								// 读取finish_award_pet
								NodeList finish_award_pet = firstTaskElement
										.getElementsByTagName("finish_award_pet");
								for (int i = 0; i < finish_award_pet
										.getLength(); i++) {
									Node finish_award_petNode = finish_award_pet
											.item(i);
									if (finish_award_petNode.getNodeType() == Node.ELEMENT_NODE) {
										Element finish_award_petElement = (Element) finish_award_petNode;
										// 读取name
										NodeList nameList = finish_award_petElement
												.getElementsByTagName("name");
										String name = nameList.item(0)
												.getChildNodes().item(0)
												.getNodeValue().trim();
										MmochatMonster monster = MmochatPetService.monsterBaseAttrData
												.get(MmochatRoleType
														.valueOf(name));
										task.getFinish_award_pet().add(
												(MmochatMonster) monster
														.getClone());
									}
								}

								// 读取finish_award_prop
								NodeList finish_award_prop = firstTaskElement
										.getElementsByTagName("finish_award_prop");
								for (int i = 0; i < finish_award_prop
										.getLength(); i++) {
									Node finish_award_propNode = finish_award_prop
											.item(i);
									if (finish_award_propNode.getNodeType() == Node.ELEMENT_NODE) {
										Element finish_award_propElement = (Element) finish_award_propNode;
										// 读取name
										NodeList nameList = finish_award_propElement
												.getElementsByTagName("name");
										String name = nameList.item(0)
												.getChildNodes().item(0)
												.getNodeValue().trim();
										MmochatPropType propType = MmochatPropType
												.valueOf(name);
										if (propType == null) {
											throw new RuntimeException(
													"任务中的使用了道具[" + name
															+ "]，此道具不存在。");
										}
										task.getFinish_award_prop().add(
												propType);
									}
								}

								// 读取finish_award_equip
								NodeList finish_award_equip = firstTaskElement
										.getElementsByTagName("finish_award_equip");
								for (int equipIndex = 0; equipIndex < finish_award_equip
										.getLength(); equipIndex++) {
									MmochatEquipAward equip = new MmochatEquipAward();
									Node finish_award_equipNode = finish_award_equip
											.item(equipIndex);
									if (finish_award_equipNode.getNodeType() == Node.ELEMENT_NODE) {
										Element finish_award_equipElement = (Element) finish_award_equipNode;
										// 读取opportunity
										NodeList opportunityList = finish_award_equipElement
												.getElementsByTagName("opportunity");
										String opportunityStr = opportunityList
												.item(0).getChildNodes()
												.item(0).getNodeValue().trim();
										int opportunity = Integer
												.parseInt(opportunityStr);
										equip.setOpportunity(opportunity);

										// 读取type
										NodeList typeList = finish_award_equipElement
												.getElementsByTagName("type");
										String typeListStr = typeList.item(0)
												.getChildNodes().item(0)
												.getNodeValue().trim();
										equip.setEquipType(MmochatEquipType
												.valueOf(typeListStr));

										// 读取level
										NodeList levelList = finish_award_equipElement
												.getElementsByTagName("level");
										String levelStr = levelList.item(0)
												.getChildNodes().item(0)
												.getNodeValue().trim();
										int level = Integer.parseInt(levelStr);
										level = level / 10 * 10;
										equip.setLevel(level);

										// quality
										NodeList qualityList = finish_award_equipElement
												.getElementsByTagName("quality");
										String qualityStr = qualityList.item(0)
												.getChildNodes().item(0)
												.getNodeValue().trim();
										equip
												.setQuality(MmochatEquipQualityType
														.valueOf(qualityStr));
										// 读取modify
										NodeList modifyList = finish_award_equipElement
												.getElementsByTagName("modify");
										String modifyStr = modifyList.item(0)
												.getChildNodes().item(0)
												.getNodeValue().trim();
										int modify = Integer
												.parseInt(modifyStr);
										if (modify < 0) {
											modify = 0;
										}
										equip.setModify(modify);
										task.getFinish_award_equips()
												.add(equip);
									}
								}

								// 读取next_taskId
								NodeList next_taskIdList = firstTaskElement
										.getElementsByTagName("next_taskId");
								if (next_taskIdList != null
										&& next_taskIdList.getLength() > 0) {
									String next_taskIdStr = next_taskIdList
											.item(0).getChildNodes().item(0)
											.getNodeValue().trim();
									int next_taskId = Integer
											.parseInt(next_taskIdStr);
									task.setNext_taskId(next_taskId);

								}

								// 读取next_taskHintName
								NodeList next_taskHintNameList = firstTaskElement
										.getElementsByTagName("next_taskHintName");
								if (next_taskHintNameList != null
										&& next_taskHintNameList.getLength() > 0) {
									String next_taskHintName = next_taskHintNameList
											.item(0).getChildNodes().item(0)
											.getNodeValue().trim();
									task
											.setNext_taskHintName(next_taskHintName);
								}

								// 读取next_taskHint
								NodeList next_taskHintList = firstTaskElement
										.getElementsByTagName("next_taskHint");
								if (next_taskHintList != null
										&& next_taskHintList.getLength() > 0) {
									String next_taskHint = next_taskHintList
											.item(0).getChildNodes().item(0)
											.getNodeValue().trim();
									task.setNext_taskHint(next_taskHint);
								}

								// 读取guide_next_taskNpcId
								NodeList guide_next_taskNpcIdList = firstTaskElement
										.getElementsByTagName("guide_next_taskNpcId");
								if (guide_next_taskNpcIdList != null
										&& guide_next_taskNpcIdList.getLength() > 0) {
									String str = guide_next_taskNpcIdList.item(
											0).getChildNodes().item(0)
											.getNodeValue().trim();
									int npcId = Integer.parseInt(str);
									task.setGuide_next_taskNpcId(npcId);
								}

								// 读取nextAccept_taskId(任务后自动接起此taskId对应的任务)
								NodeList nextAccept_taskIdList = firstTaskElement
										.getElementsByTagName("nextAccept_taskId");
								if (nextAccept_taskIdList != null
										&& nextAccept_taskIdList.getLength() > 0) {
									String nextAccept_taskIdStr = nextAccept_taskIdList
											.item(0).getChildNodes().item(0)
											.getNodeValue().trim();
									int nextAccept_taskId = Integer
											.parseInt(nextAccept_taskIdStr);
									task
											.setNextAccept_taskId(nextAccept_taskId);
								}

								// 读取battle(任务需要进行的NPC战斗)
								NodeList finish_need_battle = firstTaskElement
										.getElementsByTagName("battle");
								if (finish_need_battle.getLength() > 0) {
									Node finish_need_battleNode = finish_need_battle
											.item(0);
									if (finish_need_battleNode.getNodeType() == Node.ELEMENT_NODE) {
										Element finish_need_battleElement = (Element) finish_need_battleNode;
										// 读取npcBattle
										MmochatNpcBattle npcBattle;
										try {
											npcBattle = MmochatMainService
													.createNpcBattleFromFile(finish_need_battleElement);
										} catch (Exception e) {
											e.printStackTrace();
											throw new RuntimeException(task
													.getTaskName()
													+ ",taskId="
													+ task.getTaskId() + "，出错");
										}
										task.setFinish_need_battle(npcBattle);
									}
								}

								// 将task添加到接任务npc和交任务npc身上
								MmochatNpc npc = null;
								if (accept_npcId != null) {
									npc = MmochatNpcService
											.getNpcById(accept_npcId);
									if (npc != null) {
										npc.addTask(task);
									}
								}
								npc = MmochatNpcService
										.getNpcById(finish_npcId);
								if (npc != null) {
									npc.addTask(task);
								}

								tasks.put(task.getTaskId(), task);
							}// end of if clause
						}// end of for loop with s var
					}
				}
				log.debug("任务初始化成功!");

				// 读取日常活动
				File file = new File("base/dailyActivityList.xml");
				if (file != null && file.isFile()) {
					DocumentBuilderFactory docBuilderFactory = DocumentBuilderFactory
							.newInstance();
					DocumentBuilder docBuilder = docBuilderFactory
							.newDocumentBuilder();
					Document doc = docBuilder.parse(file);

					// normalize text redivsentation
					doc.getDocumentElement().normalize();
					NodeList listOfTask = doc.getElementsByTagName("活动");

					for (int s = 0; s < listOfTask.getLength(); s++) {
						Node firstTaskNode = listOfTask.item(s);
						if (firstTaskNode.getNodeType() == Node.ELEMENT_NODE) {
							MmochatActivityInfo activity = new MmochatActivityInfo();
							Element firstTaskElement = (Element) firstTaskNode;
							// 读取活动名称
							{
								NodeList nodeList = firstTaskElement
										.getElementsByTagName("活动名称");
								String nodeStr = nodeList.item(0)
										.getChildNodes().item(0).getNodeValue()
										.trim();
								activity.setName(nodeStr);
							}
							// 读取等级下限
							{
								NodeList nodeList = firstTaskElement
										.getElementsByTagName("等级下限");
								String nodeStr = nodeList.item(0)
										.getChildNodes().item(0).getNodeValue()
										.trim();
								int level;
								try {
									level = Integer.parseInt(nodeStr);
									activity.setMinLevel(level);
								} catch (Exception e) {
									throw new RuntimeException(
											"base/dailyActivityList.xml中等级下限不是数字，活动名:"
													+ activity.getName());
								}
							}
							// 读取等级上限
							{
								NodeList nodeList = firstTaskElement
										.getElementsByTagName("等级上限");
								String nodeStr = nodeList.item(0)
										.getChildNodes().item(0).getNodeValue()
										.trim();
								int level;
								try {
									level = Integer.parseInt(nodeStr);
									activity.setMaxLevel(level);
								} catch (Exception e) {
									throw new RuntimeException(
											"base/dailyActivityList.xml中等级上限不是数字，活动名:"
													+ activity.getName());
								}
							}
							// 读取活动时间
							{
								NodeList nodeList = firstTaskElement
										.getElementsByTagName("活动时间");
								String nodeStr = nodeList.item(0)
										.getChildNodes().item(0).getNodeValue()
										.trim();
								activity.setActivityTime(nodeStr);
							}
							// 读取活动内容
							{
								NodeList nodeList = firstTaskElement
										.getElementsByTagName("活动内容");
								String nodeStr = nodeList.item(0)
										.getChildNodes().item(0).getNodeValue()
										.trim();
								activity.setActivityInfo(nodeStr);
							}
							// 读取活动奖励
							{
								NodeList nodeList = firstTaskElement
										.getElementsByTagName("活动奖励");
								String nodeStr = nodeList.item(0)
										.getChildNodes().item(0).getNodeValue()
										.trim();
								activity.setActivityAward(nodeStr);
							}
							// 读取活动NPC
							{
								NodeList nodeList = firstTaskElement
										.getElementsByTagName("活动NPC");
								String nodeStr = nodeList.item(0)
										.getChildNodes().item(0).getNodeValue()
										.trim();
								Integer npcId = null;
								try {
									npcId = Integer.parseInt(nodeStr);
								} catch (Exception e) {
								}
								activity.setActivityNpcId(npcId);
								if (npcId == null) {
									activity.setActivityNpcName(nodeStr);
								}
							}
							// 读取组队要求
							{
								NodeList nodeList = firstTaskElement
										.getElementsByTagName("组队要求");
								String nodeStr = nodeList.item(0)
										.getChildNodes().item(0).getNodeValue()
										.trim();
								activity.setTeamNeed(nodeStr);
							}
							dailyActivities.add(activity);
						}
					}
				} else {
					throw new RuntimeException(
							"base/dailyActivityList.xml文件不存在");
				}

				// 读取日常活动
				file = new File("base/activityList.xml");
				if (file != null && file.isFile()) {
					DocumentBuilderFactory docBuilderFactory = DocumentBuilderFactory
							.newInstance();
					DocumentBuilder docBuilder = docBuilderFactory
							.newDocumentBuilder();
					Document doc = docBuilder.parse(file);

					// normalize text redivsentation
					doc.getDocumentElement().normalize();
					NodeList listOfTask = doc.getElementsByTagName("活动");

					for (int s = 0; s < listOfTask.getLength(); s++) {
						Node firstTaskNode = listOfTask.item(s);
						if (firstTaskNode.getNodeType() == Node.ELEMENT_NODE) {
							MmochatActivityInfo activity = new MmochatActivityInfo();
							Element firstTaskElement = (Element) firstTaskNode;
							// 读取活动名称
							{
								NodeList nodeList = firstTaskElement
										.getElementsByTagName("活动名称");
								String nodeStr = nodeList.item(0)
										.getChildNodes().item(0).getNodeValue()
										.trim();
								activity.setName(nodeStr);
							}
							// 读取等级下限
							{
								NodeList nodeList = firstTaskElement
										.getElementsByTagName("等级下限");
								String nodeStr = nodeList.item(0)
										.getChildNodes().item(0).getNodeValue()
										.trim();
								int level;
								try {
									level = Integer.parseInt(nodeStr);
									activity.setMinLevel(level);
								} catch (Exception e) {
									throw new RuntimeException(
											"base/dailyActivityList.xml中等级下限不是数字，活动名:"
													+ activity.getName());
								}
							}
							// 读取等级上限
							{
								NodeList nodeList = firstTaskElement
										.getElementsByTagName("等级上限");
								String nodeStr = nodeList.item(0)
										.getChildNodes().item(0).getNodeValue()
										.trim();
								int level;
								try {
									level = Integer.parseInt(nodeStr);
									activity.setMaxLevel(level);
								} catch (Exception e) {
									throw new RuntimeException(
											"base/dailyActivityList.xml中等级上限不是数字，活动名:"
													+ activity.getName());
								}
							}
							// 读取活动时间
							{
								NodeList nodeList = firstTaskElement
										.getElementsByTagName("活动时间");
								String nodeStr = nodeList.item(0)
										.getChildNodes().item(0).getNodeValue()
										.trim();
								activity.setActivityTime(nodeStr);
							}
							// 读取活动内容
							{
								NodeList nodeList = firstTaskElement
										.getElementsByTagName("活动内容");
								String nodeStr = nodeList.item(0)
										.getChildNodes().item(0).getNodeValue()
										.trim();
								activity.setActivityInfo(nodeStr);
							}
							// 读取活动奖励
							{
								NodeList nodeList = firstTaskElement
										.getElementsByTagName("活动奖励");
								String nodeStr = nodeList.item(0)
										.getChildNodes().item(0).getNodeValue()
										.trim();
								activity.setActivityAward(nodeStr);
							}
							// 读取活动NPC
							{
								NodeList nodeList = firstTaskElement
										.getElementsByTagName("活动NPC");
								String nodeStr = nodeList.item(0)
										.getChildNodes().item(0).getNodeValue()
										.trim();
								Integer npcId = null;
								try {
									npcId = Integer.parseInt(nodeStr);
								} catch (Exception e) {
								}
								activity.setActivityNpcId(npcId);
								if (npcId == null) {
									activity.setActivityNpcName(nodeStr);
								}
							}
							// 读取组队要求
							{
								NodeList nodeList = firstTaskElement
										.getElementsByTagName("组队要求");
								String nodeStr = nodeList.item(0)
										.getChildNodes().item(0).getNodeValue()
										.trim();
								activity.setTeamNeed(nodeStr);
							}
							suggestActivities.add(activity);
						}
					}
				} else {
					throw new RuntimeException("base/activityList.xml文件不存在");
				}
				log.debug("dailyActivityList与活动推荐加载成功");
			} catch (SAXParseException err) {
				log.debug("** Parsing error" + ", line " + err.getLineNumber()
						+ ", uri " + err.getSystemId());
				log.debug(" " + err.getMessage());
				err.printStackTrace();
				throw new RuntimeException("任务初始化失败,请重启!");
			} catch (SAXException e) {
				Exception x = e.getException();
				((x == null) ? e : x).printStackTrace();
				throw new RuntimeException("任务初始化失败,请重启!");
			} catch (Throwable t) {
				t.printStackTrace();
				throw new RuntimeException("任务初始化失败,请重启!");
			}
		}
	}

	// 平均每秒最多能执行大约2次，在高峰期，1500人同时在线情况下，平均每人12.5分钟会保存一次数据库
	class saveSqlAfterTaskAction implements Runnable {
		@Override
		public void run() {
			try {
				if (System.currentTimeMillis() < MmochatConstant.startSaveSqlAfterJobTick) {
					return;
				}
				if (!MmochatConstant.saveSqlAfterActiveLock) {
					needToSaveTaskSqlPlayerQueue.clear();
					return;
				}
				MmochatPlayer me = needToSaveTaskSqlPlayerQueue.poll();
				try {
					if (me != null) {
						MmochatPlayer he = MmochatMainService.offlinePlayers
								.get(me.getRoleId());
						if (he != null && me != he) {
							me = he;
						}
					}
				} catch (Exception e) {
					e.printStackTrace();
				}
				// 为防止死锁等导致一条操作无法结束，每次启动新的线程来执行
				new Thread(new doSql(me)).start();
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
	}

	class doSql extends Thread {
		MmochatPlayer me = null;

		public doSql(MmochatPlayer m) {
			me = m;
		}

		public void run() {
			try {
				if (me != null) {
					MmochatDao.updateRoleFinishTask(me);
					log.debug(me.getName() + "执行updateRoleFinishTask操作!");
				}
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
	}

	// 获取指定任务
	public static MmochatTask getTaskById(int taskId) {
		return tasks.get(taskId);
	}

	// 4.1点击npc
	@SkymobiService
	public SkymobiProtocolMessage handleC_4_1(SkymobiHandler handler,
			Mmochat_4_1C req) {
		MmochatPlayer me = MmochatMainService.getPlayerByRoleId(req, req
				.getRoleId());
		if (me == null) {
			return MmochatUtil.msgbox(req.getHallState(), "服务器忙,请稍候再试!");
		}

		MmochatNpc npc = MmochatNpcService.getNpcById(req.getNpcId());
		if (npc == null) {
			return MmochatUtil.msgbox(req.getHallState(), "目标已经离开!");
		}
		if (npc instanceof MmochatTempNpc) {
			MmochatTempNpc boss = (MmochatTempNpc) npc;
			if (boss.getState() == MmochatNpcState.离开) {
				return MmochatUtil.msgbox(req.getHallState(), "目标已经离开!");
			} else if (boss.getState() == MmochatNpcState.战斗中) {
				return MmochatUtil.msgbox(req.getHallState(), "目标正在战斗中,请稍候再来!");
			}
		}
		if (npc.getMapId() != me.getMapId()
				|| Math.abs(me.getX() - npc.getX()) > 400
				|| Math.abs(me.getY() - npc.getY()) > 400) {
			// 与NPC不在同一地图或距离太远
			boolean canRomoteVisit = false;
			for (int romoteId : romoteNpcIds) {
				if (romoteId == npc.getNpcId()) {
					// 允许远程访问
					canRomoteVisit = true;
					break;
				}
			}
			if (!canRomoteVisit) {
				return MmochatUtil.msgbox(req.getHallState(),
						"与目标距离太远!请退出游戏重新进入再试试。");
			}
		}

		// 获取所有<可接任务>,<未完成任务>,<可交任务>列表
		List<MmochatTask> canAcceptTasks = new ArrayList<MmochatTask>();
		List<MmochatTask> notFinishTasks = new ArrayList<MmochatTask>();
		List<MmochatTask> canFinishTasks = new ArrayList<MmochatTask>();
		for (MmochatTask task : npc.getTasks().values()) {
			if (task.getAccept_npcId() == npc.getNpcId()
					&& me.canAcceptTask(task.getTaskId())) {
				canAcceptTasks.add(task);
			} else if (task.getFinish_npcId() == npc.getNpcId()) {
				if (me.canFinishTask(task.getTaskId())) {
					// 可交付的任务(如果需要完成一场战斗，也认为是可交付)
					canFinishTasks.add(task);
				} else if (me.isNotFinishTask(task.getTaskId())) {
					notFinishTasks.add(task);
				}
			}
		}

		if (canAcceptTasks.size() == 0 && canFinishTasks.size() == 0
				&& notFinishTasks.size() == 0
				&& npc.getFunctionItems().size() == 0) {
			// 默认对话
			CreateMsgBoxTLVWithBmp msgbox = new CreateMsgBoxTLVWithBmp();
			msgbox.setContent(new Text(npc.getDefaultMessage()));
			msgbox.setLeftName("确定");
			msgbox.setBmpId(npc.getBmpType().getValue());
			return MmochatUtil.tlvResponse(req.getHallState(), msgbox);
		} else {
			// 可接,未完成任务,可交任务列表
			CreateTlvWin tlv = new CreateTlvWin();
			tlv.setWinId(MmochatConstant.TLV_WIN_TASKLIST);
			tlv.setWinType(WinType.List);
			tlv.setLeftName("确定");
			tlv.setRightName("返回");
			tlv.setTitle(npc.getName());
			tlv.addRightTLV(new CloseWinTLV(MmochatConstant.TLV_WIN_TASKLIST));

			int itemCount = 0;
			for (MmochatTask task : canFinishTasks) {
				tlv.addItemEvent(MmochatUtil.wrapColor(task.getTaskName()
						+ "(可交付)", Color.yellow), new ClearDataTLV(),
						new AddDataTLV(task.getTaskId()), new AddDataTLV(
								(int) npc.getNpcId()), new SendDataTLV(
								MmochatConstant.getClientModuleId(),
								MmochatMain.getModuleInstID(),
								MmochatConstant.MSGCODE_MMOCHAT_C_4_2,
								(int) req.getRoleId()));
				itemCount++;
			}
			for (MmochatTask task : canAcceptTasks) {
				tlv.addItemEvent(MmochatUtil.wrapColor(task.getTaskName(),
						Color.yellow), new ClearDataTLV(), new AddDataTLV(
						(int) task.getTaskId()), new AddDataTLV((int) npc
						.getNpcId()), new SendDataTLV(MmochatConstant
						.getClientModuleId(), MmochatMain.getModuleInstID(),
						MmochatConstant.MSGCODE_MMOCHAT_C_4_2, (int) req
								.getRoleId()));
				itemCount++;
			}
			for (MmochatTask task : notFinishTasks) {
				tlv.addItemEvent(MmochatUtil.wrapColor(task.getTaskName()
						+ "(未完成)", Color.yellow), new ClearDataTLV(),
						new AddDataTLV(task.getTaskId()), new AddDataTLV(
								(int) npc.getNpcId()), new SendDataTLV(
								MmochatConstant.getClientModuleId(),
								MmochatMain.getModuleInstID(),
								MmochatConstant.MSGCODE_MMOCHAT_C_4_2,
								(int) req.getRoleId()));
				itemCount++;
			}

			// NPC固定功能
			for (MmochatNpcItemType function : npc.getFunctionItems()) {
				tlv.addItemEvent(function.toString(), new ClearDataTLV(),
						new AddDataTLV((int) npc.getNpcId()), new AddDataTLV(
								(int) function.getValue()), new SendDataTLV(
								MmochatConstant.getClientModuleId(),
								MmochatMain.getModuleInstID(),
								MmochatConstant.MSGCODE_MMOCHAT_C_9_1,
								(int) req.getRoleId()));
				itemCount++;
			}

			if (itemCount <= 6) {
				tlv.setWinHeight(168);// 6项
			} else {
				tlv.setWinHeight(228);
			}

			tlv.addLeftTLV(new ShowWaitingMsgBoxTLV());
			return MmochatUtil.tlvResponse(req.getHallState(), tlv);
		}
	}

	public static CreateMsgBoxTLVWithBmp getTaskAcceptTalkMsg(MmochatPlayer p,
			MmochatTask task, int roleId, int taskId, int npcId) {
		CreateMsgBoxTLVWithBmp msgbox = new CreateMsgBoxTLVWithBmp();
		MmochatTaskTalk talk = task.getCurAcceptTalk(p);
		msgbox.setContent(new Text(talk.getMsg()));
		if (talk.getBmpType() != null) {
			msgbox.setBmpId(talk.getBmpType().getValue());
		}
		task.addCur_accept_talk_index();

		if (!task.isAccept_talk_over()) {
			CreateMsgBoxTLVWithBmp nextMsgbox = getTaskAcceptTalkMsg(p, task,
					roleId, taskId, npcId);
			msgbox.setLeftName("继续");
			msgbox.addLeftTLV(nextMsgbox);
		} else {
			msgbox.setLeftName("确定");
			if (task.isCanReject()) {
				msgbox.setRightName("取消");
				msgbox.addRightTLV(new CloseWinTLV());
			}
			msgbox.addLeftTLV(new ClearDataTLV());
			msgbox.addLeftTLV(new AddDataTLV((int) roleId));
			msgbox.addLeftTLV(new AddDataTLV((int) taskId));
			msgbox.addLeftTLV(new AddDataTLV((int) npcId));
			msgbox.addLeftTLV(new SendDataTLV(MmochatConstant
					.getClientModuleId(), MmochatMain.getModuleInstID(),
					MmochatConstant.MSGCODE_MMOCHAT_C_4_3, null));
			if (task.canAccept(p)) {
				// 如果在帮派、门派地图，则不寻路
				MmochatMap curMap = MmochatMapService.getMapByMapId(p
						.getMapId());
				if (curMap != null
						&& curMap.getMapId() < MmochatConstant.mapId_gangBase
						&& curMap.getMapId() != MmochatConstant.mapId_人教
						&& curMap.getMapId() != MmochatConstant.mapId_截教
						&& curMap.getMapId() != MmochatConstant.mapId_阐教) {
					// 如果可以接受此任务，则自动寻路到任务目的地
					MmochatMapPoint point = task.getGuiderPoint(p,
							MmochatTaskStateType.已接);
					if (point != null) {
						msgbox
								.addLeftTLV(new CallLocalFuncTlv(
										MmochatConstant.funcode_worldPathFunc,
										point.getMapId(), point.getX(), point
												.getY()));
					}
				}
			}
		}
		return msgbox;
	}

	public static CreateMsgBoxTLVWithBmp getTaskFinishTalkMsg(MmochatPlayer p,
			MmochatTask task, int roleId, int taskId, int npcId) {
		CreateMsgBoxTLVWithBmp msgbox = new CreateMsgBoxTLVWithBmp();
		MmochatTaskTalk talk;
		if (task == null) {
			return null;
		}
		synchronized (task) {
			talk = task.getCurFinishTalk(p);
			if (talk == null) {
				return null;
			}
			task.addCur_finish_talk_index();
		}
		msgbox.setContent(new Text(talk.getMsg()));
		if (talk.getBmpType() != null) {
			msgbox.setBmpId(talk.getBmpType().getValue());
		}

		if (!task.isFinish_talk_over()) {
			CreateMsgBoxTLVWithBmp nextMsgbox = getTaskFinishTalkMsg(p, task,
					roleId, taskId, npcId);
			msgbox.setLeftName("继续");
			msgbox.addLeftTLV(nextMsgbox);
		} else {
			msgbox.setLeftName("确定");
			msgbox.setRightName("取消");
			msgbox.addRightTLV(new CloseWinTLV());
			msgbox.addLeftTLV(new ClearDataTLV());
			msgbox.addLeftTLV(new AddDataTLV((int) roleId));
			msgbox.addLeftTLV(new AddDataTLV((int) taskId));
			msgbox.addLeftTLV(new AddDataTLV((int) npcId));
			msgbox.addLeftTLV(new SendDataTLV(MmochatConstant
					.getClientModuleId(), MmochatMain.getModuleInstID(),
					MmochatConstant.MSGCODE_MMOCHAT_C_4_3, null));
		}

		return msgbox;
	}

	// 4.2点击npc指定任务
	@SkymobiService
	public SkymobiProtocolMessage handleC_4_2(SkymobiHandler handler,
			Mmochat_4_2C req) {
		MmochatPlayer p = MmochatMainService.getPlayerByRoleId(req, req
				.getRoleId());
		if (p == null) {
			return MmochatUtil.msgbox(req.getHallState(), "服务器忙,请稍候再试!");
		}
		MmochatNpc npc = MmochatNpcService.getNpcById(req.getNpcId());
		if (npc == null) {
			return MmochatUtil.msgbox(req.getHallState(), "目标已经离开!");
		}
		MmochatTask task = npc.getTask(req.getTaskId());
		if (task == null) {
			return MmochatUtil.msgbox(req.getHallState(), "没有找到此任务!");
		}
		MmochatTask myTask = p.getTaskById(task.getTaskId());
		if (task.getAccept_npcId() == npc.getNpcId()
				&& p.canAcceptTask(req.getTaskId())) {
			// 超过最大任务数,则无法再接新任务
			if (p.isTaskFull()) {
				return MmochatUtil.msgbox(req.getHallState(), "您当前已经有"
						+ MmochatConstant.maxUnfinishedTaskNum
						+ "个任务在做了,无法再接新任务!");
			}
			if (task.canAccept(p)) {
				// 接新任务
				MmochatTask newTask = task.getClone();
				p.addTask(newTask);
				if (newTask.getAccept_talk().size() == 0) {
					// 没有对话则直接接受任务
					newTask.setTaskState(MmochatTaskStateType.已接);
					CreateMsgBoxTLV msgbox = new CreateMsgBoxTLV();
					msgbox.setLeftName("确定");
					try {
						MmochatDao.updateRoleTasks(p);
					} catch (Exception e) {
						e.printStackTrace();
						msgbox.setContent(new Text("服务器忙,任务接受失败!"));
						return MmochatUtil.tlvResponse(req.getHallState(),
								new CloseWinTLV(
										MmochatConstant.TLV_WIN_TASKLIST),
								msgbox);
					}
					msgbox.setContent(new Text("任务接受成功!"));
					// 更新NPC任务标志:接任务和交任务NPC
					MmochatNpc finishNpc = MmochatNpcService.getNpcById(newTask
							.getFinish_npcId());
					Mmochat_4_14S npcPack = new Mmochat_4_14S();
					npcPack.addNpc(npc);
					if (finishNpc != null) {
						npcPack.addNpc(finishNpc);
					}
					npcPack.setMe(p);
					MmochatUtil.sendCommonPack(p, npcPack);

					// 更新任务列表
					Mmochat_4_11S pack = new Mmochat_4_11S();
					pack.setActionType(0);
					pack.setMe(p);
					pack.setTask(newTask);
					// Mmochat_4_8S pack = new Mmochat_4_8S();
					// pack.setHintKey(newTask.getHintKey());
					// pack.setHintWord(newTask.getHintWord());
					MmochatUtil.sendCommonPack(p, pack);
					return MmochatUtil.tlvResponse(req.getHallState(),
							new CloseWinTLV(MmochatConstant.TLV_WIN_TASKLIST),
							msgbox);
				} else {
					CreateMsgBoxTLVWithBmp msgbox = getTaskAcceptTalkMsg(p,
							newTask, req.getRoleId(), req.getTaskId(), req
									.getNpcId());
					return MmochatUtil.tlvResponse(req.getHallState(),
							new CloseWinTLV(MmochatConstant.TLV_WIN_TASKLIST),
							msgbox);
				}
			} else {
				return MmochatUtil.msgbox(req.getHallState(), "您现在还无法接此任务!");
			}
		} else if (myTask != null && myTask.getFinish_npcId() == npc.getNpcId()) {
			if (p.canFinishTask(req.getTaskId())) {
				// 已完成,可交付
				if (myTask.getFinish_talk().size() == 0) {
					// 没有对话则直接完成任务
					// 交任务对话结束，是否需要进行NPC战斗
					if (myTask.needBattleBeforeFinish()) {
						// 玩家队伍
						List<MmochatPlayer> myTeam = new ArrayList<MmochatPlayer>();
						if (p.isInTeam()) {
							MmochatTeam team = MmochatTeamService.teams.get(p
									.getTeamId());
							if (team == null) {
								p.leaveTeam();
								myTeam.add(p);
							} else {
								for (Integer roleId : team.getMemberId()
										.values()) {
									MmochatPlayer member = MmochatMainService
											.getRoleFromBuffer(roleId);
									if (member != null) {
										myTeam.add(member);
									}
								}
							}
						} else {
							myTeam.add(p);
						}

						// 进入任务NPC战斗
						if (npc instanceof MmochatTempNpc) {
							MmochatTempNpc boss = (MmochatTempNpc) npc;
							synchronized (boss) {
								if (boss.getState() == MmochatNpcState.空闲) {
									boss.setState(MmochatNpcState.战斗中);
								} else if (boss.getState() == MmochatNpcState.离开) {
									return MmochatUtil.msgbox(req
											.getHallState(), "怪物已经离开!");
								} else if (boss.getState() == MmochatNpcState.战斗中) {
									return MmochatUtil.msgbox(req
											.getHallState(), "怪物正在战斗中,请稍候再来!");
								}
							}
						}
						MmochatBattleService.enterNpcPk(p.getMapId(), (byte) p
								.getLine(), myTeam, p.getRoleId(), myTask, req
								.getNpcId());
						return null;
					} else {
						dealFinishingTask(p, myTask);
						return MmochatUtil.msgbox(req.getHallState(), "任务完成!");
					}
				} else {
					CreateMsgBoxTLVWithBmp msgbox = getTaskFinishTalkMsg(p,
							myTask, req.getRoleId(), req.getTaskId(), req
									.getNpcId());
					return MmochatUtil.tlvResponse(req.getHallState(),
							new CloseWinTLV(MmochatConstant.TLV_WIN_TASKLIST),
							msgbox);
				}
			} else {
				// 任务未完成，提示未完成条件(不包括需要一场NPC战斗)
				String msg = "你先去";
				// 杀怪数量
				for (MmochatKillMonster kill : myTask.getKillList()) {
					if (kill.getCurKillMonsterNum() < kill.getMonsterNum()) {
						msg += "消灭"
								+ (kill.getMonsterNum() - kill
										.getCurKillMonsterNum()) + "个"
								+ kill.getMonsterType().toString() + ",";
					}
				}

				// 收集材料
				for (MmochatMaterial material : myTask
						.getFinish_need_materials()) {
					if (material.getNum() > 0) {
						int myNum = p.getPackageObjNum(material.getType());
						if (myNum < material.getNum()) {
							msg += "收集" + (material.getNum() - myNum) + "个"
									+ material.getType().toString() + ",";
						}
					}
				}

				// 收集药品
				for (MmochatDrug drug : myTask.getFinish_need_drugs()) {
					if (drug.getNum() > 0) {
						int myNum = p.getPackageObjNum(drug.getType());
						if (myNum < drug.getNum()) {
							msg += "采购" + (drug.getNum() - myNum) + "个"
									+ drug.toString() + ",";
						}
					}
				}
				// 金钱
				if (myTask.getFinish_need_money() > 0) {
					if (p.getSmall_money() < myTask.getFinish_need_money()) {
						msg += "准备"
								+ MmochatUtil.getColorMoney(myTask
										.getFinish_need_money()) + "文钱,";
					}
				}

				// 战绩
				if (p.getZhanji() < myTask.getFinish_need_zhanji()) {
					msg += "准备" + myTask.getFinish_need_zhanji() + "点战绩,";
				}
				msg += "再来找我吧!";
				return MmochatUtil.msgbox(req.getHallState(), msg);
			}
		}
		return MmochatUtil.msgbox(req.getHallState(), npc.getDefaultMessage());
	}

	public static void dealFinishingTask(MmochatPlayer me, MmochatTask myTask) {
		int oldLevel = me.getLevel();
		myTask.finishTask(me);

		// 下发删除任务
		Mmochat_4_12S taskPack = new Mmochat_4_12S();
		taskPack.setTaskId(myTask.getTaskId());
		MmochatUtil.sendCommonPack(me, taskPack);

		// 增加过度任务
		if (myTask.getNext_taskId() != null) {
			MmochatTask hintTask = new MmochatTask();
			hintTask.setTaskId(myTask.getNext_taskId());
			hintTask.setTaskName(myTask.getNext_taskHintName());
			hintTask.setTaskDetail(myTask.getNext_taskHint());
			hintTask.setTaskType(MmochatTaskType.过渡任务);
			hintTask.setTaskState(MmochatTaskStateType.已接);
			me.addTask(hintTask);
			// 下发增加任务
			MmochatTask nextTask = tasks.get(myTask.getNext_taskId());
			if (nextTask != null) {
				hintTask.setFinish_npcId(nextTask.getAccept_npcId());
			}
			Mmochat_4_11S pack = new Mmochat_4_11S();
			pack.setActionType(0);
			pack.setMe(me);
			pack.setTask(hintTask);
			MmochatUtil.sendCommonPack(me, pack);

			// 如果可以接受此任务，则自动寻路到任务目的地
			MmochatMapPoint point = nextTask.getGuiderPoint(me);
			if (point != null) {
				CtrlTLVStructureRequest tracePack = MmochatUtil
						.tlvResponseWithoutHallState(new CallLocalFuncTlv(
								MmochatConstant.funcode_worldPathFunc, point
										.getMapId(), point.getX(), point.getY()));
				MmochatUtil.sendCommonPack(me, tracePack);
			}
		}

		// 增加新任务
		if (myTask.getNextAccept_taskId() != null) {
			MmochatTask tmp = tasks.get(myTask.getNextAccept_taskId());
			if (tmp == null) {
				tmp = YBTasks.get(myTask.getNextAccept_taskId());
			}
			if (tmp != null) {
				MmochatTask nextTask = tmp.getClone();
				// TODO:任务ID转换:帮派总管(-1)
				if (nextTask.getAccept_npcId() == MmochatConstant.npcId_gangNpc2_inFile
						|| nextTask.getFinish_npcId() == MmochatConstant.npcId_gangNpc2_inFile) {
					if (me.hasGang()) {
						MmochatGang gang = MmochatGangService.getGangById(me
								.getGangId());
						if (gang != null) {
							if (nextTask.getAccept_npcId() == MmochatConstant.npcId_gangNpc2_inFile) {
								nextTask
										.setAccept_npcId(MmochatConstant.npcId_gangNpc2Base
												+ gang.getId());
							} else if (nextTask.getFinish_npcId() == MmochatConstant.npcId_gangNpc2_inFile) {
								nextTask
										.setFinish_npcId(MmochatConstant.npcId_gangNpc2Base
												+ gang.getId());
							}
						}
					} else {
						log.error("没有帮派，但在做帮派任务。。");
					}
				}
				nextTask.setTaskState(MmochatTaskStateType.已接);
				me.addTask(nextTask);

				// 下发增加任务
				Mmochat_4_11S pack = new Mmochat_4_11S();
				pack.setActionType(0);
				pack.setMe(me);
				pack.setTask(nextTask);
				MmochatUtil.sendCommonPack(me, pack);

				// 如果可以接受此任务，则自动寻路到任务目的地
				MmochatMapPoint point = nextTask.getGuiderPoint(me);
				if (point != null) {
					CtrlTLVStructureRequest tracePack = MmochatUtil
							.tlvResponseWithoutHallState(new CallLocalFuncTlv(
									MmochatConstant.funcode_worldPathFunc,
									point.getMapId(), point.getX(), point
											.getY()));
					MmochatUtil.sendCommonPack(me, tracePack);
				}

				// Mmochat_4_8S pack = new Mmochat_4_8S();
				// pack.setHintKey(nextTask.getHintKey());
				// pack.setHintWord(nextTask.getHintWord());
				// MmochatUtil.sendCommonPack(me, pack);
			}
		}

		// 更新NPC任务标志
		Mmochat_4_14S npcPack = new Mmochat_4_14S();
		npcPack.setMe(me);
		// 更新当前NPC
		MmochatNpc npc = MmochatNpcService.getNpcById(myTask.getFinish_npcId());
		if (npc != null) {
			npcPack.addNpc(npc);
		}
		// 更新下一个任务NPC
		MmochatTask nextAcceptTask = myTask.getTaskAfterThis();
		if (nextAcceptTask != null) {
			MmochatNpc nextAcceptNpc = MmochatNpcService
					.getNpcById(nextAcceptTask.getAccept_npcId());
			if (nextAcceptNpc != null) {
				if (nextAcceptNpc.getMapId() == me.getMapId()) {
					npcPack.addNpc(nextAcceptNpc);
				}
			}
			MmochatNpc nextFinishNpc = MmochatNpcService
					.getNpcById(nextAcceptTask.getFinish_npcId());
			if (nextFinishNpc != null) {
				if (nextFinishNpc.getMapId() == me.getMapId()) {
					npcPack.addNpc(nextFinishNpc);
				}
			}
		}
		if (npcPack.hasNpc()) {
			MmochatUtil.sendCommonPack(me, npcPack);
		}

		// 显示路线指引
		if (myTask.getGuide_next_taskNpcId() != null) {
			MmochatNpc targetNpc = MmochatNpcService.getNpcById(myTask
					.getGuide_next_taskNpcId());
			Mmochat_4_9S pack = new Mmochat_4_9S();
			if (targetNpc != null) {
				pack.setMapId(targetNpc.getMapId());
				pack.setX(targetNpc.getX());
				pack.setY(targetNpc.getY());
			} else {
				pack.setMapId(-1);
				pack.setX((short) 0);
				pack.setY((short) 0);
			}
			MmochatUtil.sendCommonPack(me, pack);
		}

		// 如果任务已完成,为减少保存数据库的量,将去除任务介绍和对话等无用的文字
		if (me.getTasks().containsValue(myTask)) {
			myTask.getAccept_talk().clear();
			myTask.getFinish_talk().clear();
			myTask.getKillList().clear();
			myTask.getFinish_need_materials().clear();
			myTask.getFinish_need_drugs();
			myTask.setTaskDetail("");
			myTask.setFinish_need_battles(null);
			myTask.getFinish_award_materials().clear();
			myTask.getFinish_award_drugs().clear();
			myTask.getFinish_award_equips().clear();
			myTask.getFinish_award_pet().clear();
			myTask.getFinish_award_prop().clear();
			myTask.setNext_taskHintName(null);
			myTask.setNext_taskHint(null);
		}

		// 道具:血池法池效果
		MmochatPropService.useAutoAddBloodSpritProp(me);

		// 更新头像图标信息
		Mmochat_1_7S pack = new Mmochat_1_7S(me.getLevel() > oldLevel);
		pack.setMe(me);
		MmochatUtil.sendCommonPack(me, pack);

		// 放入队列中
		if (!needToSaveTaskSqlPlayerQueue.contains(me)
				&& !MmochatGmService.isSystemExit()) {
			needToSaveTaskSqlPlayerQueue.add(me);
		}
	}

	// 4.3点击npc对话框确定键
	@SkymobiService
	public SkymobiProtocolMessage handleC_4_3(SkymobiHandler handler,
			Mmochat_4_3C req) {
		MmochatPlayer p = MmochatMainService.getPlayerByRoleId(req, req
				.getRoleId());
		if (p == null) {
			return MmochatUtil.msgbox(req.getHallState(), "服务器忙,请稍候再试!");
		}
		if (req.getNpcId() == null) {
			return MmochatUtil.msgbox(req.getHallState(),
					"系统出错，请退出游戏到冒泡大厅，再重新进入!");
		}
		MmochatNpc npc = MmochatNpcService.getNpcById((int) req.getNpcId());
		if (npc == null) {
			return MmochatUtil.msgbox(req.getHallState(), "目标已经离开!");
		}
		MmochatTask myTask = p.getTaskById(req.getTaskId());
		if (myTask == null) {
			log.debug("Mmochat_4_3C, error = 1");
			return MmochatUtil.msgbox(req.getHallState(), "您还没有此任务!");
		}
		if (myTask.getTaskState() == MmochatTaskStateType.未接) {
			if (myTask.getAccept_npcId() == npc.getNpcId()) {
				if (myTask.isAccept_talk_over()) {
					// 接任务对话结束,接受任务
					if (myTask.canAccept(p)) {
						myTask.setTaskState(MmochatTaskStateType.已接);
						try {
							MmochatDao.updateRoleTasks(p);
						} catch (Exception e) {
							e.printStackTrace();
						}
						// 更新NPC任务标志:接任务和交任务NPC
						MmochatNpc finishNpc = MmochatNpcService
								.getNpcById(myTask.getFinish_npcId());
						Mmochat_4_14S npcPack = new Mmochat_4_14S();
						npcPack.addNpc(npc);
						if (finishNpc != null) {
							npcPack.addNpc(finishNpc);
						}
						npcPack.setMe(p);
						MmochatUtil.sendCommonPack(p, npcPack);

						// 下发增加任务
						Mmochat_4_11S pack = new Mmochat_4_11S();
						pack.setActionType(0);
						pack.setMe(p);
						pack.setTask(myTask);
						MmochatUtil.sendCommonPack(p, pack);
						// Mmochat_4_8S pack = new Mmochat_4_8S();
						// pack.setHintKey(myTask.getHintKey());
						// pack.setHintWord(myTask.getHintWord());
						// MmochatUtil.sendCommonPack(p, pack);
						return null;
					} else {
						return MmochatUtil.msgbox(req.getHallState(),
								"您现在还无法接此任务!");
					}
				} else {
					// 继续对话
					CreateMsgBoxTLVWithBmp msgbox = getTaskAcceptTalkMsg(p,
							myTask, req.getRoleId(), req.getTaskId(), (int) req
									.getNpcId());

					return MmochatUtil.tlvResponse(req.getHallState(), msgbox);
				}
			}
		} else if (myTask.getTaskState() == MmochatTaskStateType.已接) {
			if (myTask.getFinish_npcId() == npc.getNpcId()) {
				if (myTask.isFinish_talk_over()) {
					if (myTask.canFinish(p)) {
						// 交任务对话结束，是否需要进行NPC战斗
						if (myTask.needBattleBeforeFinish()) {
							// 玩家队伍
							List<MmochatPlayer> myTeam = new ArrayList<MmochatPlayer>();
							if (p.isInTeam()) {
								MmochatTeam team = MmochatTeamService.teams
										.get(p.getTeamId());
								if (team == null) {
									p.leaveTeam();
									myTeam.add(p);
								} else {
									for (Integer roleId : team.getMemberId()
											.values()) {
										MmochatPlayer member = MmochatMainService
												.getRoleFromBuffer(roleId);
										if (member != null) {
											myTeam.add(member);
										}
									}
								}
							} else {
								myTeam.add(p);
							}
							// 进入任务NPC战斗
							if (npc instanceof MmochatTempNpc) {
								MmochatTempNpc boss = (MmochatTempNpc) npc;
								synchronized (boss) {
									if (boss.getState() == MmochatNpcState.空闲) {
										boss.setState(MmochatNpcState.战斗中);
									} else if (boss.getState() == MmochatNpcState.离开) {
										return MmochatUtil.msgbox(req
												.getHallState(), "怪物已经离开!");
									} else if (boss.getState() == MmochatNpcState.战斗中) {
										return MmochatUtil.msgbox(req
												.getHallState(),
												"怪物正在战斗中,请稍候再来!");
									}
								}
							}
							MmochatBattleService.enterNpcPk(p.getMapId(),
									(byte) p.getLine(), myTeam, p.getRoleId(),
									myTask, (int) req.getNpcId());
						} else {
							dealFinishingTask(p, myTask);
						}
						return null;
					} else {
						// 任务未完成，提示未完成条件(不包括需要一场NPC战斗)
						String msg = "你先去";
						// 杀怪数量
						for (MmochatKillMonster kill : myTask.getKillList()) {
							if (kill.getCurKillMonsterNum() < kill
									.getMonsterNum()) {
								msg += "消灭"
										+ (kill.getMonsterNum() - kill
												.getCurKillMonsterNum()) + "个"
										+ kill.getMonsterType().toString()
										+ ",";
							}
						}

						// 收集材料
						for (MmochatMaterial material : myTask
								.getFinish_need_materials()) {
							if (material.getNum() > 0) {
								int myNum = p.getPackageObjNum(material
										.getType());
								if (myNum < material.getNum()) {
									msg += "收集" + (material.getNum() - myNum)
											+ "个"
											+ material.getType().toString()
											+ ",";
								}
							}
						}

						// 收集药品
						for (MmochatDrug drug : myTask.getFinish_need_drugs()) {
							if (drug.getNum() > 0) {
								int myNum = p.getPackageObjNum(drug.getType());
								if (myNum < drug.getNum()) {
									msg += "采购" + (drug.getNum() - myNum) + "个"
											+ drug.toString() + ",";
								}
							}
						}
						// 金钱
						if (myTask.getFinish_need_money() > 0) {
							if (p.getSmall_money() < myTask
									.getFinish_need_money()) {
								msg += "准备"
										+ MmochatUtil.getColorMoney(myTask
												.getFinish_need_money())
										+ "文钱,";
							}
						}

						// 战绩
						if (p.getZhanji() < myTask.getFinish_need_zhanji()) {
							msg += "准备" + myTask.getFinish_need_zhanji()
									+ "点战绩,";
						}
						msg += "再来找我吧!";
						return MmochatUtil.msgbox(req.getHallState(), msg);
					}
				} else {
					// 继续对话
					CreateMsgBoxTLVWithBmp msgbox = getTaskFinishTalkMsg(p,
							myTask, req.getRoleId(), req.getTaskId(), (int) req
									.getNpcId());
					return MmochatUtil.tlvResponse(req.getHallState(), msgbox);
				}
			}
		}
		return MmochatUtil.msgbox(req.getHallState(), npc.getDefaultMessage());
	}

	// 检查过期任务
	@SkymobiService
	public SkymobiProtocolMessage handleC_4_4(SkymobiHandler handler,
			Mmochat_4_4C req) {
		MmochatPlayer me = MmochatMainService.getPlayerByRoleId(req, req
				.getRoleId());
		if (me == null) {
			return null;
		}

		for (MmochatTask task : me.getUnfinishedTasks()) {
			// 删除过期临时任务
			if (task.isInvalid()) {
				me.getTasks().remove(task.getTaskId());
				// 下发删除任务
				Mmochat_4_12S taskPack = new Mmochat_4_12S();
				taskPack.setTaskId(task.getTaskId());
				MmochatUtil.sendCommonPack(me, taskPack);
				continue;
			}
		}
		return null;
	}

	// 查看玩家已接任务详情
	@SkymobiService
	public SkymobiProtocolMessage handleC_4_5(SkymobiHandler handler,
			Mmochat_4_5C req) {
		MmochatPlayer me = MmochatMainService.getPlayerByRoleId(req, req
				.getRoleId());
		if (me == null) {
			return MmochatUtil.msgbox(req.getHallState(), "服务器忙,请稍候再试!");
		}

		// 查看任务详情
		MmochatTask myTask = me.getTaskById(req.getTaskId());
		if (myTask == null) {
			return MmochatUtil.msgbox(req.getHallState(), "没有找到此任务信息!");
		}

		CreateTlvWin tlv = new CreateTlvWin();

		tlv.setWinType(WinType.Text);
		tlv.setRightName("返回");
		tlv.setTitle(myTask.getTaskName());
		tlv.addRightTLV(new CloseWinTLV(MmochatConstant.TLV_WIN_TASKINFO));
		tlv.setWinId(MmochatConstant.TLV_WIN_TASKINFO);
		String taskDetail = "";

		// 任务寻路信息
		MmochatMapPoint guider = myTask.getGuiderPoint(me);

		if (myTask.getTaskType() != MmochatTaskType.过渡任务
				&& myTask.getTaskType() != MmochatTaskType.寻宝任务) {
			// 交任务NPC
			MmochatNpc npc = MmochatNpcService.getNpcById(myTask
					.getFinish_npcId());

			taskDetail += "[任务介绍]" + "\n" + myTask.getTaskDetail();
			taskDetail += "\n\n";
			taskDetail += "[任务进度]";
			if (me.canFinishTask(req.getTaskId())
					&& myTask.getFinish_need_battles() == null) {
				taskDetail += "\n可交付!";
			} else {
				// 杀怪数量
				for (MmochatKillMonster kill : myTask.getKillList()) {
					taskDetail += "\n需要消灭";
					taskDetail += MmochatUtil.wrapColor(kill.getMonsterType()
							.toString(), Color.yellow);
					taskDetail += kill.getMonsterNum() + "个,已消灭"
							+ kill.getCurKillMonsterNum() + "个!";
				}

				// 收集材料
				for (MmochatMaterial material : myTask
						.getFinish_need_materials()) {
					if (material.getNum() > 0) {
						int myNum = me.getPackageObjNum(material.getType());
						myNum = Math.min(myNum, material.getNum());
						taskDetail += "\n需要收集";
						taskDetail += MmochatUtil.wrapColor(material.getType()
								.toString(), Color.yellow);
						taskDetail += material.getNum() + "个,已收集" + myNum
								+ "个!";
					}
				}

				// 收集药品
				for (MmochatDrug drug : myTask.getFinish_need_drugs()) {
					if (drug.getNum() > 0) {
						int myNum = me.getPackageObjNum(drug.getType());
						myNum = Math.min(myNum, drug.getNum());
						taskDetail += "\n需要采购";
						taskDetail += MmochatUtil.wrapColor(drug.getType()
								.toString(), Color.yellow);
						taskDetail += drug.getNum() + "个,已采购" + myNum + "个!";
					}
				}
				// 金钱
				if (myTask.getFinish_need_money() > 0) {
					taskDetail += "\n需要提交";
					taskDetail += MmochatUtil.getColorMoney(myTask
							.getFinish_need_money())
							+ "文钱,现有"
							+ MmochatUtil.getColorMoney(me.getSmall_money())
							+ "文!";
				}

				// 战绩
				if (me.getZhanji() < myTask.getFinish_need_zhanji()) {
					taskDetail += "\n需要扣除";
					taskDetail += MmochatUtil.getColorMoney(myTask
							.getFinish_need_zhanji())
							+ "点战绩,现有" + me.getZhanji() + "点战绩!";
				}

				// NPC战斗
				if (myTask.getFinish_need_battles() != null) {
					taskDetail += "\n需要完成一次战斗!";
				}
			}

			// 交任务NPC
			taskDetail += "\n\n";
			if (npc != null) {
				MmochatMap map = MmochatMapService.maps.get(npc.getMapId());
				if (map != null) {
					taskDetail += "[交任务NPC]\n" + npc.getName() + "("
							+ map.getMapName() + ":" + npc.getX() + ","
							+ npc.getY() + ")";
				}
			}

			// 任务进度
			if (myTask.getTaskType().isCanDrop()) {
				CreateMsgBoxTLV msgbox = new CreateMsgBoxTLV();
				msgbox.setContent(new Text("你确定要放弃这个任务么?"));
				msgbox.setLeftName("放弃");
				msgbox.setRightName("取消");
				msgbox.addLeftTLV(new ClearDataTLV());
				msgbox.addLeftTLV(new AddDataTLV((int) me.getRoleId()));
				msgbox.addLeftTLV(new SendDataTLV(MmochatConstant
						.getClientModuleId(), MmochatMain.getModuleInstID(),
						MmochatConstant.MSGCODE_MMOCHAT_C_4_7, (int) myTask
								.getTaskId()));
				ShowWaitingMsgBoxTLV wait = new ShowWaitingMsgBoxTLV();
				wait.setShowCancel(false);
				msgbox.addLeftTLV(wait);

				ShowPopupMenuTLV menu = new ShowPopupMenuTLV();
				if (guider != null) {
					menu.addItemEvent("自动寻路", new CallLocalFuncTlv(
							MmochatConstant.funcode_worldPathFunc, guider
									.getMapId(), guider.getX(), guider.getY()));
				}
				menu.addItemEvent("放弃任务", msgbox);
				tlv.setLeftName("菜单");
				tlv.addLeftTLV(menu);
			} else {
				if (guider != null) {
					tlv.addLeftTLV(new CallLocalFuncTlv(
							MmochatConstant.funcode_worldPathFunc, guider
									.getMapId(), guider.getX(), guider.getY()));
					tlv.setLeftName("寻路");
				}
			}
		} else {
			MmochatTask task = tasks.get(myTask.getTaskId());
			if (task != null) {
				// 接任务等级
				taskDetail += "[任务等级要求]\n";
				taskDetail += task.getAccept_minLevel() + "级";
				// 接任务NPC
				taskDetail += "\n\n";
				MmochatNpc npc = MmochatNpcService.getNpcById(task
						.getAccept_npcId());
				if (npc != null) {
					MmochatMap map = MmochatMapService.maps.get(npc.getMapId());
					if (map != null) {
						taskDetail += "[接任务NPC]\n" + npc.getName() + "("
								+ map.getMapName() + ":" + npc.getX() + ","
								+ npc.getY() + ")\n\n";
					}
				}

				if (guider != null) {
					tlv.addLeftTLV(new CallLocalFuncTlv(
							MmochatConstant.funcode_worldPathFunc, guider
									.getMapId(), guider.getX(), guider.getY()));
					tlv.setLeftName("寻路");
				}
			}
			taskDetail += "[任务介绍]" + "\n" + myTask.getTaskDetail();
		}
		tlv.setContent(new Text(taskDetail));
		return MmochatUtil.tlvResponse(req.getHallState(), tlv);

	}

	// 放弃任务
	@SkymobiService
	public SkymobiProtocolMessage handleC_4_7(SkymobiHandler handler,
			Mmochat_4_7C req) {
		MmochatPlayer me = MmochatMainService.getPlayerByRoleId(req, req
				.getRoleId());
		if (me == null) {
			return MmochatUtil.msgbox(req.getHallState(), "服务器忙,请稍候再试!");
		}
		MmochatTask task = me.getTasks().remove(req.getTaskId());
		try {
			MmochatDao.updateRoleTasks(me);
		} catch (Exception e) {
			e.printStackTrace();
			return MmochatUtil.msgbox(req.getHallState(), "服务器忙,请稍候再试!");
		}

		if (task != null) {
			MmochatNpc npc = MmochatNpcService.getNpcById(task
					.getFinish_npcId());
			if (npc != null) {
				// 更新NPC任务标志
				Mmochat_4_14S npcPack = new Mmochat_4_14S();
				npcPack.addNpc(npc);
				npcPack.setMe(me);
				MmochatUtil.sendCommonPack(me, npcPack);
			}
		}

		// 下发删除任务
		Mmochat_4_12S taskPack = new Mmochat_4_12S();
		taskPack.setTaskId(req.getTaskId());
		MmochatUtil.sendCommonPack(me, taskPack);

		return MmochatUtil.tlvResponse(req.getHallState(), new CloseWinTLV(
				MmochatConstant.TLV_WIN_TASKINFO));
	}

	// 查看可接任务详情
	@SkymobiService
	public SkymobiProtocolMessage handleC_4_6(SkymobiHandler handler,
			Mmochat_4_6C req) {
		MmochatPlayer p = MmochatMainService.getPlayerByRoleId(req, req
				.getRoleId());
		if (p == null) {
			return MmochatUtil.msgbox(req.getHallState(), "服务器忙,请稍候再试!");
		}
		MmochatTask task = tasks.get(req.getTaskId());
		if (task == null) {
			return MmochatUtil.msgbox(req.getHallState(), "没有找到此任务信息!");
		}

		CreateTlvWin tlv = new CreateTlvWin();

		tlv.setWinType(WinType.Text);
		tlv.setRightName("返回");
		tlv.setTitle(task.getTaskName());
		tlv.addRightTLV(new CloseWinTLV());
		String taskDetail = "";

		// 接任务NPC
		MmochatNpc npc = MmochatNpcService.getNpcById(task.getAccept_npcId());
		if (npc != null) {
			MmochatMap map = MmochatMapService.maps.get(npc.getMapId());
			if (map != null) {
				taskDetail += "[接任务NPC]\n" + npc.getName() + "("
						+ map.getMapName() + ":" + npc.getX() + ","
						+ npc.getY() + ")\n\n";
			}
		} else {
			// 交任务NPC
			npc = MmochatNpcService.getNpcById(task.getFinish_npcId());
			if (npc != null) {
				MmochatMap map = MmochatMapService.maps.get(npc.getMapId());
				if (map != null) {
					taskDetail += "[交任务NPC]\n" + npc.getName() + "("
							+ map.getMapName() + ":" + npc.getX() + ","
							+ npc.getY() + ")\n\n";
				}
			}
		}
		taskDetail += "[任务介绍]" + "\n" + task.getTaskDetail();
		tlv.setContent(new Text(taskDetail));

		// 任务寻路信息
		MmochatMapPoint guider = task.getGuiderPoint(p);
		if (guider != null) {
			tlv.addLeftTLV(new CallLocalFuncTlv(
					MmochatConstant.funcode_worldPathFunc, guider.getMapId(),
					guider.getX(), guider.getY()));
			tlv.setLeftName("寻路");
		}
		return MmochatUtil.tlvResponse(req.getHallState(), tlv);
	}

	// 获取缓存到终端的任务活动信息
	public static Mmochat_4_4S getTaskBufferedInfo(MmochatPlayer me) {
		Mmochat_4_4S pack = new Mmochat_4_4S();
		pack.setMe(me);
		if (me != null) {
			// 当前任务
			for (MmochatTask task : me.getUnfinishedTasks()) {
				// 删除过期临时任务
				if (task.isInvalid()) {
					me.getTasks().remove(task.getTaskId());
					continue;
				}
				pack.addUnfinishedTaskList(task);
			}

			// 可接任务
			for (MmochatTask t : tasks.values()) {
				if (t.getTaskId() > 0) {
					if (t.isShowInTaskList() && me.canAcceptTask(t.getTaskId())) {
						pack.addCanAcceptTaskList(t);
					}
				}
			}

			// 日常活动
			pack.setDailyActivities(dailyActivities);

			// 推荐活动
			for (MmochatActivityInfo t : suggestActivities) {
				if (me.getLevel() >= t.getMinLevel()
						&& me.getLevel() <= t.getMaxLevel()) {
					pack.addSuggestActivities(t);
				}
			}
		}
		return pack;
	}

	// 查看日常活动/推荐活动详情
	@SkymobiService
	public SkymobiProtocolMessage handleC_4_10(SkymobiHandler handler,
			Mmochat_4_10C req) {
		MmochatPlayer p = MmochatMainService.getPlayerByRoleId(req, req
				.getRoleId());
		if (p == null) {
			return MmochatUtil.msgbox(req.getHallState(), "服务器忙,请稍候再试!");
		}

		MmochatActivityInfo curActivity = null;
		for (MmochatActivityInfo activity : dailyActivities) {
			if (activity.getId() == req.getActivityId()) {
				curActivity = activity;
				break;
			}
		}
		if (curActivity == null) {
			for (MmochatActivityInfo activity : suggestActivities) {
				if (activity.getId() == req.getActivityId()) {
					curActivity = activity;
					break;
				}
			}
		}

		if (curActivity == null) {
			return MmochatUtil.msgbox(req.getHallState(), "暂无此活动信息!");
		}

		CreateTlvWin tlv = new CreateTlvWin();

		tlv.setWinType(WinType.Text);
		tlv.setRightName("返回");
		tlv.setTitle(curActivity.getName());
		tlv.addRightTLV(new CloseWinTLV());
		String detail = "";
		detail += MmochatUtil.wrapColor("活动时间：", Color.yellow);
		detail += "\n" + curActivity.getActivityTime();
		detail += MmochatUtil.wrapColor("\n等级限制：", Color.yellow);
		detail += "\n" + curActivity.getMinLevel() + "-"
				+ curActivity.getMaxLevel();
		detail += MmochatUtil.wrapColor("\n活动奖励：", Color.yellow);
		detail += "\n" + curActivity.getActivityAward();
		detail += MmochatUtil.wrapColor("\n队伍要求：", Color.yellow);
		detail += "\n" + curActivity.getTeamNeed();
		detail += MmochatUtil.wrapColor("\n活动内容：", Color.yellow);
		detail += "\n" + curActivity.getActivityInfo();

		tlv.setContent(new Text(detail));
		return MmochatUtil.tlvResponse(req.getHallState(), tlv);
	}

	// 更新可接任务
	@SkymobiService
	public SkymobiProtocolMessage handleC_4_13(SkymobiHandler handler,
			Mmochat_4_13C req) {
		MmochatPlayer me = MmochatMainService.getPlayerByRoleId(req, req
				.getRoleId());
		if (me == null) {
			return null;
		}
		// 可接任务
		Mmochat_4_13S pack = new Mmochat_4_13S();
		pack.setMe(me);
		for (MmochatTask t : tasks.values()) {
			if (t.getTaskId() > 0) {
				if (t.isShowInTaskList() && me.canAcceptTask(t.getTaskId())) {
					pack.addCanAcceptTaskList(t);
				}
			}
		}
		return pack;
	}
}
